﻿using Core.Framework;
using Environment.Interfaces;
using Microsoft.JSInterop;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Threading.Tasks;

namespace Dashboard
{
    public class WindowsHelper
    {
        private readonly IJSRuntime _jsRuntime;

        private readonly INodeService _iNodeService;
        public WindowsHelper(IJSRuntime jsRuntime, INodeService INodeService = null)
        {
            _jsRuntime = jsRuntime;
            _iNodeService = INodeService;
        }
        /// <summary>
        /// 设置LocalStorage
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task SetLocalStorageAsync(string key, string value)
        {
            //await _jsRuntime.InvokeVoidAsync("localStorageSetItem", DESEncrypt.Encrypt(key), DESEncrypt.Encrypt(value));
            await _jsRuntime.InvokeVoidAsync("setCookie", DESEncrypt.Encrypt(key), DESEncrypt.Encrypt(value), 999);
        }

        public async Task SetLocalStorageAsync<T>(T value) where T : class
        {
            // await _jsRuntime.InvokeVoidAsync("localStorageSetItem", DESEncrypt.Encrypt(typeof(T).Name), DESEncrypt.Encrypt(value.TryToJson()));
            await _jsRuntime.InvokeVoidAsync("setCookie", DESEncrypt.Encrypt(typeof(T).Name), DESEncrypt.Encrypt(value.TryToJson()), 999);
        }

        public async Task SetLocalStorageAsync<T>(string key, T value) where T : class
        {
            // await _jsRuntime.InvokeVoidAsync("localStorageSetItem", DESEncrypt.Encrypt(key), DESEncrypt.Encrypt(value.TryToJson()));
            await _jsRuntime.InvokeVoidAsync("setCookie", DESEncrypt.Encrypt(key), DESEncrypt.Encrypt(value.TryToJson()), 999);
        }
        /// <summary>
        /// 获取LocalStorage
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<string> GetLocalStorageAsync(string key)
        {
            // var value = await _jsRuntime.InvokeAsync<string>("localStorageGetItem", DESEncrypt.Encrypt(key));
            var value = await _jsRuntime.InvokeAsync<string>("getCookie", DESEncrypt.Encrypt(key));
            return DESEncrypt.Decrypt(value);
        }

        public async Task<T> GetLocalStorageAsync<T>(string key) where T : class
        {
            // var value = await _jsRuntime.InvokeAsync<string>("localStorageGetItem", DESEncrypt.Encrypt(key));
            var value = await _jsRuntime.InvokeAsync<string>("getCookie", DESEncrypt.Encrypt(key));
            return DESEncrypt.Decrypt(value).TryToEntity<T>();
        }

        public async Task<T> GetLocalStorageAsync<T>() where T : class
        {
            // var value = await _jsRuntime.InvokeAsync<string>("localStorageGetItem", DESEncrypt.Encrypt(typeof(T).Name));
            var value = await _jsRuntime.InvokeAsync<string>("getCookie", DESEncrypt.Encrypt(typeof(T).Name));
            return DESEncrypt.Decrypt(value).TryToEntity<T>();
        }

        public async Task HideLoadingAsync()
        {
            await _jsRuntime.InvokeVoidAsync("LoadingComplate");
        }

        public async Task HideAsync(string selector, int fadeOut = 300)
        {
            await _jsRuntime.InvokeVoidAsync("HideBox", selector, fadeOut);
        }

        public async Task ShowAsync(string selector)
        {
            await _jsRuntime.InvokeVoidAsync("ShowBox", selector);
        }

        public async Task ShowLoadingAsync()
        {
            await _jsRuntime.InvokeVoidAsync("ShowLoading");
        }


        public async Task ConsoleLogAsync(params object[] values)
        {
#if DEBUG
            await _jsRuntime.InvokeVoidAsync("console.log", values);
#endif
        }

        public async Task ConsoleErrorAsync(params object[] values)
        {
            await _jsRuntime.InvokeVoidAsync("console.error", values);
        }

        public async Task Open(params object[] values)
        {
            await _jsRuntime.InvokeVoidAsync("windowOpen", values);
        }

        public async Task CreateMap()
        {

            if (string.IsNullOrWhiteSpace(AppSetting.iToolLoggerSqlString))
            {
                await Task.CompletedTask;
                return;
            }

            try
            {
                Dictionary<string, string> sqllist = new Dictionary<string, string>();
                //有无状态响应时间
                sqllist.Add("StateResponseTime", "select [isUseState],avg([runTimeTotalMilliseconds]) as runTime,count(1) as runCount FROM LogFunction group by [isUseState];");
                //有状态无状态函数占比
                sqllist.Add("StateGDP", "select [isUseState],avg([runTimeTotalMilliseconds]) as runTime,count(1) as runCount FROM LogFunction  where DateDiff(dd,[createTime],getdate()) <= 7 group by [isUseState]");
                //故障率
                sqllist.Add("FailureRate", "select count(1) as runCount, sum(case when[responseState] = 200 then 1 else 0 end) successCount from LogFunction where DateDiff(dd,[createTime],getdate()) <= 7");
                //故障率较高的函数
                sqllist.Add("FailureRateFun", "select top 5 [requestModuleName],[requestFunctionName],count(1) as runCount FROM LogFunction where [responseState] <> 200 and  DateDiff(dd,[createTime],getdate()) <= 7 group by [requestModuleName],[requestFunctionName] order by runCount desc");

                var tab = await SqlQueryAsync(sqllist);
                await _jsRuntime.InvokeVoidAsync("createmap", Dtb2Json(tab));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        
        public async Task UserCount(params object[] values)
        {
            await _jsRuntime.InvokeVoidAsync("userCount", values);
        }

        public async Task SetTitleAsync(string title = null)
        {
            if (!string.IsNullOrWhiteSpace(Startup.WebSiteTitle))
            {
                if (title != null)
                {
                    title += " - " + Startup.WebSiteTitle;
                }
                else
                {
                    title = Startup.WebSiteTitle;
                }
            }

            if (string.IsNullOrWhiteSpace(title))
            {
                title = "iTool Gateway";
            }

            await _jsRuntime.InvokeVoidAsync("setTitle", title);
        }

        public async Task<string> GetInputValueAsync(string id)
        {
            var value = await _jsRuntime.InvokeAsync<string>("getInputValue", id);
            return value;
        }

        public async Task<string> GetHostAsync()
        {
            var value = await _jsRuntime.InvokeAsync<string>("getHost");
            return value;
        }


        public async Task<string> GetHrefAsync()
        {
            var value = await _jsRuntime.InvokeAsync<string>("getHref");
            return value;
        }

        public async Task<string> GetPathAsync()
        {
            var value = await _jsRuntime.InvokeAsync<string>("getPath");
            return value;
        }
        public async Task<Dictionary<string, DataTable>> SqlQueryAsync(Dictionary<string, string> sqllist)
        {
            Dictionary<string, DataTable> result = new Dictionary<string, DataTable>();
            await using (SqlConnection connection = new SqlConnection(AppSetting.iToolLoggerSqlString))
            {
                await connection.OpenAsync();
                SqlCommand command = new SqlCommand();
                foreach (var item in sqllist)
                {
                    command.Connection = connection;
                    command.CommandText = item.Value;
                    var reader = await command.ExecuteReaderAsync();
                    DataTable table = new DataTable();
                    table.Load(reader);
                    result.Add(item.Key, table);
                }
            }
            return result;
        }
        public static ArrayList Dtb2Json(Dictionary<string, DataTable> sqllist)
        {
            ArrayList dictlist = new ArrayList();
            foreach (var item in sqllist)
            {
                ArrayList dic = new ArrayList();
                foreach (DataRow dr in item.Value.Rows)
                {
                    System.Collections.Generic.Dictionary<string, object> drow = new System.Collections.Generic.Dictionary<string, object>();
                    foreach (DataColumn dc in item.Value.Columns)
                    {
                        drow.Add(dc.ColumnName, dr[dc.ColumnName]);
                    }
                    dic.Add(drow);

                }
                System.Collections.Generic.Dictionary<string, object> cty = new System.Collections.Generic.Dictionary<string, object>();
                cty.Add(item.Key, dic);
                dictlist.Add(cty);

            }
            return dictlist;
        }

    }


}
